package com.zzg.util;

import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;

import com.zzg.consts.Constants;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class IpUtils {
	 private IpUtils(){
	        throw new IllegalStateException("Utility class");
	    }
	    public static String getIpAddr(HttpServletRequest request) {
	        String unknown = "unknown";
	        if (request == null) {
	            return unknown;
	        }
	        String ip = request.getHeader("x-forwarded-for");
	        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
	            ip = request.getHeader("Proxy-Client-IP");
	        }
	        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
	            ip = request.getHeader("X-Forwarded-For");
	        }
	        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
	            ip = request.getHeader("WL-Proxy-Client-IP");
	        }
	        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
	            ip = request.getHeader("X-Real-IP");
	        }

	        if (ip == null || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
	            ip = request.getRemoteAddr();
	        }

	        return "0:0:0:0:0:0:0:1".equals(ip) ? Constants.LOCAL_IP : ip;
	    }

	    public static boolean internalIp(String ip) {
	        byte[] addr = textToNumericFormatV4(ip);
	        return internalIp(addr) || Constants.LOCAL_IP.equals(ip);
	    }

	    private static boolean internalIp(byte[] addr) {
	        if(addr == null || addr.length<1){
	            return false;
	        }
	        final byte b0 = addr[0];
	        final byte b1 = addr[1];
	        // 10.x.x.x/8
	        final byte section1 = 0x0A;
	        // 172.16.x.x/12
	        final byte section2 = (byte) 0xAC;
	        final byte section3 = (byte) 0x10;
	        final byte section4 = (byte) 0x1F;
	        // 192.168.x.x/16
	        final byte section5 = (byte) 0xC0;
	        final byte section6 = (byte) 0xA8;
	        switch (b0) {
	            case section1:
	                return true;
	            case section2:
	                if (b1 >= section3 && b1 <= section4) {
	                    return true;
	                }else {
	                    return false;
	                }
	            case section5:
	                if(b1 == section6){
	                    return true;
	                }else {
	                    return false;
	                }
	            default:
	                return false;
	        }
	    }

	    /**
	     * 将IPv4地址转换成字节
	     *
	     * @param text IPv4地址
	     * @return byte 字节
	     */
	    public static byte[] textToNumericFormatV4(String text) {
	        byte[] emptyByte = new byte[0];
	        if (text.length() == 0) {
	            return emptyByte;
	        }

	        byte[] bytes = new byte[4];
	        String[] elements = text.split("\\.", -1);
	        try {
	            long l;
	            int i;
	            switch (elements.length) {
	                case 1:
	                    l = Long.parseLong(elements[0]);
	                    if ((l < 0L) || (l > 4294967295L)) {
	                        return emptyByte;
	                    }
	                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
	                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
	                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
	                    bytes[3] = (byte) (int) (l & 0xFF);
	                    break;
	                case 2:
	                    l = Integer.parseInt(elements[0]);
	                    if ((l < 0L) || (l > 255L)) {
	                        return emptyByte;
	                    }
	                    bytes[0] = (byte) (int) (l & 0xFF);
	                    l = Integer.parseInt(elements[1]);
	                    if ((l < 0L) || (l > 16777215L)) {
	                        return emptyByte;
	                    }
	                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
	                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
	                    bytes[3] = (byte) (int) (l & 0xFF);
	                    break;
	                case 3:
	                    for (i = 0; i < 2; ++i) {
	                        l = Integer.parseInt(elements[i]);
	                        if ((l < 0L) || (l > 255L)) {
	                            return emptyByte;
	                        }
	                        bytes[i] = (byte) (int) (l & 0xFF);
	                    }
	                    l = Integer.parseInt(elements[2]);
	                    if ((l < 0L) || (l > 65535L)) {
	                        return emptyByte;
	                    }
	                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
	                    bytes[3] = (byte) (int) (l & 0xFF);
	                    break;
	                case 4:
	                    for (i = 0; i < 4; ++i) {
	                        l = Integer.parseInt(elements[i]);
	                        if ((l < 0L) || (l > 255L)) {
	                            return emptyByte;
	                        }
	                        bytes[i] = (byte) (int) (l & 0xFF);
	                    }
	                    break;
	                default:
	                    return emptyByte;
	            }
	        } catch (NumberFormatException e) {
	            return emptyByte;
	        }
	        return bytes;
	    }

	    public static String getHostIp() {
	        try {
	            return InetAddress.getLocalHost().getHostAddress();
	        } catch (UnknownHostException e) {
	            log.error(e.getMessage(), e);
	        }
	        return "127.0.0.1";
	    }

	    public static String getHostName() {
	        try {
	            return InetAddress.getLocalHost().getHostName();
	        } catch (UnknownHostException e) {
	            log.error(e.getMessage(), e);
	        }
	        return "未知";
	    }
}
